//**************************************************************************************************************
// CLASS: Assembler
//
// DESCRIPTION
// Main class for the K1 assembler.
//
// AUTHOR INFORMATION
// Matthew Recchia
// Bryce Muzzy
// Ariana Griego
// Daniel Ortiz
//**************************************************************************************************************
// Write the preprocessor guard.
#ifndef ASSEMBLER_HPP
#define ASSEMBLER_HPP

#include "DataSegment.hpp"
#include "Instr.hpp"
#include "InstrTypeB.hpp"
#include "InstrTypeR.hpp"
#include "InstrTypeRI.hpp"
#include "InstrTypeRV.hpp"
#include "Lex.hpp"
#include "TextSegment.hpp"
#include "Types.hpp"

//==============================================================================================================
// CLASS: Assembler
//==============================================================================================================

// Write the class declaration for Assembler.
class Assembler {

public:
	Assembler(std::string pSrcFname, std::string mBinFrame);
	int Run();
	~Assembler();

protected:
	void Assemble(uint const pPass);
	void AssembleDirective(std::string const& pDirective);
	Instr* AssembleInstr(std::string const& pMnemonic, std::string const& mLabel = "");
	Instr* AssembleInstrTypeB(std::string const& pMnemonic, std::string const& mLabel = "");
	Instr* AssembleInstrTypeN(std::string const& pMnemonic, std::string const& mLabel = "");
	InstrTypeR* AssembleInstrTypeR(std::string const& pMnemonic, std::string const& mLabel = "");
	InstrTypeRI* AssembleInstrTypeRI(std::string const& pMnemonic, std::string const& mLabel = "");
	InstrTypeRV* AssembleInstrTypeRV(std::string const& pMnemonic, std::string const& mLabel = "");
	void AssembleLabel(std::string const& pName);
	void AssembleVariable(std::string const& pName);
	void WriteBinary() const;

private:
	std::string mBinFname;
	Address mCurrAddr;
	DataSegment mDataSeg;
	Lex mLex;
	std::string mSrcFname;
	TextSegment mTextSeg;
	Assembler();
	Assembler(Assembler const& pAssembler);
	Assembler& operator=(Assembler const& pAssembler);

};

// End the preprocessor guard.
#endif
